package com.ada.secure;

import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.modes.CFBBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.security.SecureRandom;

public class StringKeyEncryptionExample {
    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        // Initialize AES engine and CFB mode
        AESEngine aesEngine = new AESEngine();
        BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CFBBlockCipher(aesEngine, 128), new ZeroBytePadding());

        // Convert the string key to bytes using a hash function
        String stringKey = "MySecretKey123";
        byte[] keyBytes = hashStringToBytes(stringKey, 128); // 128-bit key

        // Set up key and IV
        KeyParameter keyParameter = new KeyParameter(keyBytes);
        cipher.init(true, keyParameter); // Encryption mode

        // Data to be encrypted
        String plaintext = "Hello, String Key Encryption!";
        byte[] plaintextBytes = plaintext.getBytes();

        // Encrypt the data
        byte[] ciphertext = new byte[cipher.getOutputSize(plaintextBytes.length)];
        int len = cipher.processBytes(plaintextBytes, 0, plaintextBytes.length, ciphertext, 0);
        len += cipher.doFinal(ciphertext, len);

        System.out.println("Plaintext: " + plaintext);
        System.out.println("Ciphertext: " + new String(ciphertext));

        // Decrypt the data
        cipher.init(false, keyParameter); // Decryption mode
        byte[] decrypted = new byte[cipher.getOutputSize(len)];
        len = cipher.processBytes(ciphertext, 0, len, decrypted, 0);
        len += cipher.doFinal(decrypted, len);

        System.out.println("Decrypted: " + new String(decrypted));
    }

    // Convert a string to bytes using a hash function
    public static byte[] hashStringToBytes(String input, int outputLength) {
        // Use a hash function (e.g., SHA-256) to convert the string to bytes
        // In this example, we're using a simple approach for illustration
        byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);
        byte[] outputBytes = new byte[outputLength / 8]; // Convert bits to bytes
        System.arraycopy(inputBytes, 0, outputBytes, 0, Math.min(inputBytes.length, outputBytes.length));
        return outputBytes;
    }
}
